package com.jse.mvc;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

import javax.script.ScriptException;

import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Files;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.adaptor.WhaleAdaptor;
import org.nutz.mvc.annotation.AdaptBy;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.GET;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.upload.TempFile;

import com.jse.plug.JseSession;
import com.jse.service.NashornService;

@IocBean
public class DefaultAction {

	Log log = Logs.get();

	@Inject
	NashornService nashornService;

	@At("/")
	@Ok("jse:view")
	public Object index(@Param("..") NutMap param,JseSession session) {
		String jjs = "index";
		String name = "index";

		Object obj = process(jjs, name, param, session);
		return view(jjs, obj);
	}

	@At("/?")
	@Ok("jse:view")
	public Object index(String jjs,@Param("..") NutMap param, JseSession session) {
		String name = "index";

		Object obj = process(name, jjs, param, session);// 因1级比较特殊
		return view(jjs, obj);
	}

	@At("/?/?")
	@Ok("jse:view")
	@GET
	public Object get_jjs(String jjs, String name,@Param("..") NutMap param, JseSession session) {
		if (Strings.isNumber(name)) {
			param.put("id", name);
			name = jjs;
		} else if (name.length() > 30) {
			param.put("id", name);
			name = jjs;
		}
		Object obj = process(jjs, name, param, session);
		return view(jjs + "/" + name, obj);
	}

	@At("/?/?")
	@Ok("jse:view")
	@POST
	@AdaptBy(type = WhaleAdaptor.class, args = { "ioc:jseUpload" })
	public Object post_jjs(String jjs, String name, @Param("::") NutMap param, JseSession session) {
		NutMap tbl = new NutMap();
		param.forEach((k, v) -> {
			if (v instanceof String[]) {
				tbl.put(k, Arrays.asList(v));
			} else if (v instanceof TempFile) {
				TempFile tf = (TempFile) v;
				String newfilePath = upload(tf);
				tbl.put(k, newfilePath);
			} else if (v instanceof TempFile[]) {
				TempFile[] tfs = (TempFile[]) v;
				ArrayList<String> fs = new ArrayList<String>();
				for (TempFile tf : tfs) {
					fs.add(upload(tf));
				}
				tbl.put(k, fs);
			} else if (v instanceof List) {
				LinkedList<?> list = (LinkedList<?>) v;
				ArrayList<Object> fs = new ArrayList<Object>();
				list.forEach(lv -> {
					if (lv instanceof TempFile) {
						fs.add(upload((TempFile) lv));
					} else {
						fs.add(lv);
					}
				});
				tbl.put(k, fs);
			} else {
				if (k.endsWith("_time")) {
					tbl.put(k, Times.parseq("yyyy-MM-dd HH:mm:ss", v.toString()));
				} else {// 最后普通类型
					tbl.put(k, v);
				}
			}
		});
		Object obj = process(jjs, name, tbl, session);
		return view(jjs + "/" + name, obj);
	}

	@At("/?/?/?")
	@Ok("jse:view")
	public Object _jjs(String jjs, String name, String id,@Param("..") NutMap param, JseSession session) {
		param.put("id", id);
		Object obj = process(jjs, name, param, session);
		return view(jjs + "/" + name, obj);
	}

	@At("/?/?/?/?")
	@Ok("jse:view")
	public Object _jjs(String jjs, String name, String pname, String pid,@Param("..") NutMap param, JseSession session) {
		param.put(pname, pid);
		Object obj = process(jjs, name, param, session);
		return view(jjs + "/" + name, obj);
	}

	@At("/?/?/?/?/*")
	@Ok("jse:view")
	public Object _jjs_(String jjs, String name, String pname, String pid,@Param("..") NutMap param, JseSession session) {
		param.put(pname, pid);
		List<String> pars = Mvcs.getActionContext().getPathArgs();
		try {
			for (int i = 3; i < pars.size(); i++) {
				param.put(pars.get(i), pars.get(i + 1));
			}
		} catch (Exception e) {
			log.warnf("路径参数不对称,最后一位参数%s没有加入", pars.get(pars.size() - 1));
		}
		Object obj = process(jjs, name, param, session);
		return view(jjs + "/" + name, obj);
	}

	private Object process(String jjs, String name, NutMap param, JseSession session) {
		Object rtv = null;
		try {
			rtv = nashornService.run(jjs, name, param, session);
		} catch (NoSuchMethodException e) {
			log.warnf("%s.jjs执行函数%s,报错:%s", jjs, name,e);
		} catch (ScriptException e) {
			log.warnf("%s.jjs执行函数函数%s出错:%s", jjs, name, e);
		}
		return rtv;
	}

	private Object view(String view, Object obj) {
		Mvcs.getReq().setAttribute("view", view);
		return obj;
	}

	private String upload(TempFile tf) {
		File f = tf.getFile(); // 这个是保存的临时文件
		String prefix = f.getName().substring(f.getName().lastIndexOf("."));
		// FieldMeta meta = tf.getMeta(); // 这个原本的文件信息
		// String oldName = meta.getFileLocalName(); // 这个时原本的文件名称
		String str = Mvcs.getServletContext().getRealPath("/").replace("\\", "/");
		String appName = str.substring(0, str.lastIndexOf("/"));
		appName = appName.substring(appName.lastIndexOf("/"));
		String webPath = str.substring(0, str.indexOf("tomcat") + 7) + "webapps/";
		String filePath = str.substring(0, str.indexOf("tomcat") + 7) + "webapps/upload" + appName + "/file";
		String newfilePath = filePath;
		try {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
			String dateString = simpleDateFormat.format(new Date());
			String fid = UUID.randomUUID().toString();
			filePath = filePath + "/" + dateString + "/" + fid + prefix;
			Files.copyFile(f, new File(filePath));
			newfilePath = filePath.replace(webPath, "");
		} catch (Exception e) {
			// 文件上传复制失败
			log.error("file upload copy fail! err_msg :", e);
		}
		return newfilePath;
	}
}
